package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.core.page.TableDataInfo;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.dto.DeviceDataPageReqDto;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.vo.iot.IotMsgHeader;
import com.zzyl.nursing.vo.iot.IotMsgNotifyData;
import com.zzyl.nursing.vo.iot.IotMsgService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.service.IDeviceDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import static com.zzyl.common.constant.CacheConstants.IOT_DEVICE_LAST_DATA;

/**
 * 设备数据Service业务层处理
 * 
 * @author lhs
 * @date 2025-06-03
 */
@Slf4j
@Service
public class DeviceDataServiceImpl extends ServiceImpl<DeviceDataMapper, DeviceData> implements IDeviceDataService {
    @Autowired
    private DeviceDataMapper deviceDataMapper;

    @Autowired
    private DeviceServiceImpl deviceService;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private StringRedisTemplate stringredisTemplate;

    /**
     * 查询设备数据
     *
     * @param id 设备数据主键
     * @return 设备数据
     */
    @Override
    public DeviceData selectDeviceDataById(Long id) {
        return getById(id);
    }

    /**
     * 查询设备数据列表
     *
     * @param dto 设备数据
     * @return 设备数据
     */
    @Override
    public TableDataInfo<DeviceData> selectDeviceDataList(DeviceDataPageReqDto dto) {
        Page<DeviceData> page = Page.of(dto.getPageNum(), dto.getPageSize());
        lambdaQuery().eq(StringUtils.hasText(dto.getDeviceName()),DeviceData::getDeviceName,dto.getDeviceName() )
              .eq(StringUtils.hasText(dto.getFunctionId()),DeviceData::getFunctionId,dto.getFunctionId())
              .ge(dto.getStartTime() != null,DeviceData::getAlarmTime,dto.getStartTime())
              .lt(dto.getEndTime() != null,DeviceData::getAlarmTime,dto.getEndTime()).page(page);
        TableDataInfo<DeviceData> tableDataInfo = new TableDataInfo<>();
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setRows(page.getRecords());
        tableDataInfo.setCode(200);
        tableDataInfo.setMsg("操作成功");


        return tableDataInfo;
    }

    /**
     * 新增设备数据
     *
     * @param deviceData 设备数据
     * @return 结果
     */
    @Override
    public int insertDeviceData(DeviceData deviceData) {
        return save(deviceData) ? 1 : 0;
    }

    /**
     * 修改设备数据
     *
     * @param deviceData 设备数据
     * @return 结果
     */
    @Override
    public int updateDeviceData(DeviceData deviceData) {
        return updateById(deviceData) ? 1 : 0;
    }

    /**
     * 批量删除设备数据
     *
     * @param ids 需要删除的设备数据主键
     * @return 结果
     */
    @Override
    public int deleteDeviceDataByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除设备数据信息
     *
     * @param id 设备数据主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteDeviceDataById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    @Override
    public void batchInsertData(IotMsgNotifyData data) {
        //通过header中的device_id来获取设备信息
        IotMsgHeader header = data.getHeader();
      Device  device =   deviceMapper.selectOne(new LambdaQueryWrapper<Device>().eq(Device::getIotId, header.getDeviceId()));

        if (device == null) {
            //说明设备不存在
            log.info("设备不存在");
        }
        List<IotMsgService> services = data.getBody().getServices();
        for (IotMsgService service : services) {
            String eventTime = service.getEventTime();
            LocalDateTime localDateTime = deviceService.getLocalDateTime(eventTime);
            //模型数据，模型数据是body里面的services中的properties
            Map<String, Object> properties = service.getProperties();
            //遍历properties得到map里面每一个值
            List<DeviceData> pojoList = properties.entrySet().stream().map(entry -> {
                //把device拷贝给pojo对象
                DeviceData pojo = BeanUtil.toBean(device, DeviceData.class);
                //因为拷贝的过程中会覆盖掉pojo的id，所有设置为空，主键自增长
                pojo.setId(null);
                //key刚好是功能名称
                pojo.setFunctionId(entry.getKey());
                //值
                pojo.setDataValue(entry.getValue().toString());
                //补充device没有的内容，因为Remark是接入位置的名字，而id只是编号，所以要用device的Remark
                pojo.setAccessLocation(device.getRemark());

                pojo.setAlarmTime(localDateTime);
                //下面这四个是有自动填充
                pojo.setCreateTime(null);
                pojo.setUpdateTime(null);
                pojo.setCreateBy(null);
                pojo.setUpdateBy(null);

                return pojo;
            }).collect(Collectors.toList());
            saveBatch(pojoList);
            stringredisTemplate.opsForHash().put(CacheConstants.IOT_DEVICE_LAST_DATA,header.getDeviceId(), JSONUtil.toJsonStr(data));
        }
    }
}